package com.homework.ch05;
/*
* 1.面向对象编程（oop）思路
*   面向对象的特点：1。一切皆为对象，使用对象之间的交互来实现功能2.可以将大问题细分成多个小问题3.程序员冲执行者变成了指挥官
*   面向过程的特点(pop)：从0到1，一步一步实现
*   面向对象的语言特征 封装（实现了信息的隐藏）继承（实现代码重用）多态（灵活，接口统一）
*   面向对象的语言有什么 c++，python java
*   面向对象思路：创建对象->使用对象->指挥对象，如果没有对象就先创建对象
* 拓展：ooa（面向对象的分析）ood（面向对象的设计）
* 2.对象的理解
*   一切皆为对象
*   对象由对象组成
*   对象也由属性和行为
*   具有相同属性和行为的对象可以归为一类
*   对象时类的实例化，是具体的
* 3.类的理解
*   将所有具有相同属性和行为的对象抽象为一个类
*   类是引用类型中的一种
*   类是对象的抽象
* 4.类和对象的关系
*   类是对象的抽象/模板，对象是类的实例化/实体
*   类是抽象的，对象是具体的 比如动物是抽象的而橘猫是具体的
* 5.创建类和使用类里面的方法和属性
*   5.1创建类
*      1.定义类 权限修饰符（一个.java中只有一个public） class 类名（大驼峰）
*      2.创建类的成员变量 权限修饰符 数据类型 成员变量；成员变量不赋值就是其数据类型的默认值，如果初始化就是初始化的抓值
*      3.创建成员方法 权限修饰符 函数返回值 成员方法名（形参列表）{函数体} 使用小驼峰
*   5.2.类自己使用自己的成员属性和成员方法
*       使用类内部的成员变量 直接使用变量名 当形参变量名和成员变量名重复时一定使用this.变量名
 *      使用类内部的成员方法 直接调用成员方法 使用this.方法调用
 * 成员变量和成员方法是个体的，静态方法和静态变量是集体的
* 6.创建对象使用对象的属性和方法
*   6.1实例化对象 类名 对象名=new 类名();
*   6.2对象使用对象的成员属性和成员方法
*       对象使用对象的成员属性 公开的：对象名.成员属性 私有的：使用get/set函数 没有赋值就是各个数据类型对应的默认值，赋值后就是赋值的值
*       对象使用对象的成员方法 公开的 对象名.成员方法调用
* 7.封装
*   什么是封装？封装是隐藏属性和实现细节，对外提供公共访问的方式
*   为什么要封装（优点）？
*       1.用方法来访问成员变量，提高了代码的安全性
*       2.对方法进行了封装，提高了代码的复用性
*       3.隐藏了实现细节，对外提供了公共访问，简单
*   怎么封装？或者叫封装思路是什么？
*       1.封装的原则：隐藏不对外显示的内容，隐藏属性，对外提供公共访问方式来访问属性
*       2.具体封装 使用private修饰符来修饰成员变量，使用getxxx/sexxxt公共方法来访问成员属性，getxxx方法获取值，setxxx方法赋值
* 8.构造函数
*   什么叫构造函数？在创建对象的同时会自动调用构造方法
*   如何定义和使用构造函数？
*       定义构造函数：权限访问修饰符 类名（参数列表）{方法体}
*       使用构造函数 类名 对象名=new 类名（参数）
*   构造函数的注意点：
*       1.权限访问修饰符一般是public 不写返回值（啥也没有包括void） 构造方法名==类名
*       2.创建对象时自动调用，每创建一次对象就会调用一次构造方法 不能手动调用
*       3.构造方法可以重载
*       4.不写构造方法时会创建空构造方法，一旦写了就不会创建空构造方法，要使用空构造方法就需要自己创建空构造方法
* 9.this的三种用法 this指调用该函数的对象的引用 哪个对象调用就是哪个对象的引用（地址）
*   1.this.成员变量 当形参变量名和成员变量名字冲突时必须使用this.成员变量 如果不冲突可以不使用
*   2.this.成员方法调用 调用成员方法 也可以直接调用
*   3.this() 在构造方法中调用其他构造方法，this(参数列表)必须放在构造器的第一行有效代码
*10.画出内存图（不赋值的内存图 赋值的内存图 构造方法的内存图）要求：new之前的内存图 new之后的内存图 以及剩余操作后的内存图
* // 文件： Student.java
public class Student {
    String name;
    int age;
}
* // 文件： Stu.java (根据你的图，主类名可能是Stu)
public class Stu {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.name = "tom";
        stu.age = 20;
    }
}
* 内存基础：
* 栈区：存放局部变量和函数栈帧的，方法的结束随之销毁
* 堆区：存放一切引用类型，自动垃圾回收机制会自动释放
* 方法区：将相关的.class文件中加载进方法区，具体包括（类的名字，权限修饰符，字段名，方法名）
* 过程：
*     1.编译
*       编译期间，javac命令会将源文件编译成为字节码文件（Student.class stu.class），存储的是字段，修饰符，方法（只存储一次），完整的类名的二进制形式，此时是存储在硬盘的静态文件
*     2.运行
*       方法区：
*       类加载：会将相关的.class加载进入方法区（类名，字段名，方法名（方法地址），修饰符），这里包括了Student类和stu类的类名字段名方法名修饰符
*       栈区：
*       调用main方法：在栈区中创建main的函数栈帧
*       new之前创建变量stu，此时将stu放入main函数的函数栈帧中默认是null
*       堆区：
*       new之后先在堆区根据方法区的模板开辟空间存放Student的对象实例，只存储成员属性；
*       然后初始化为各个类型对应的默认值，如果初始化就变成初始化之后的值
*       如果有构造函数就在这一步执行构造函数
*       返回堆区这块空间的地址存储到stu中
*       栈区：
*       stu.name根据地址找到stu的name，由于我没有赋值所以刚开始这个字符串指向的是空值，我将”tom“给name后，首先会在堆区开辟一个空间用来存储tom字符串然后返回地址给name
*       stu.age就是直接找到age修改为20
*       //如果是调用成员函数的话，会在模板区中找到对应的函数
*       //如果调用方法的话就需要创建函数栈帧，一次创建一个函数栈帧；
*       main结束，函数栈帧销毁，局部变量也不存在了，堆空间被自动垃圾回收机制释放了
*总结：类本身是存储在方法区的，只有在实例化的对象时，栈区存储的时对象的地址（对象名），堆区存储变量本身
* 11.有时间复习一下函数重载
*   函数名相同，参数列表不同（数量不同，类型不同，顺序不同）
* */
//5.创建学生类和使用类的属性和方法
//5.1创建类
public class Stu {
    //1.定义类的成员变量 权限修饰符 数据类型 成员变量名；
    //不赋值就是默认值，赋值也就是为每一个实例的对象都赋值
    //封装的思想是对属性私有，对方法公开
    private String name;
    private int age;

    //2.定义类的成员方法 权限修饰符 成员方法返回值 成员方法名（形参列表）{成员函数体}
    public void sayHello()
    {
        //5.21既然类也是有成员属性和成员方法的，使用类的属性就是直接写出变量名或者使用this.变量名
        //直接使用变量名
        System.out.println(name+":hello!");
        //使用this.成员变量
        System.out.println(this.name+":helloworld");
    }
    public void say()
    {
        //5.22使用类的方法：直接调用方法或者使用this关键字
        //直接调用方法
        sayHello();
        //使用this.成员方法调用
        this.sayHello();
    }
    public void setName(String name)
    {
        this.name=name;
    }
    public void setAge(int age)
    {
        this.age=age;
    }
    public String getName()
    {
        return this.name;
    }
    public int getAge()
    {
        return this.age;
    }
    protected void printf(){
        System.out.println("nihao");
    }
}
